package com.icode50.spring.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.camunda.bpm.engine.RepositoryService;
import org.camunda.bpm.engine.RuntimeService;
import org.camunda.bpm.engine.TaskService;
import org.camunda.bpm.engine.repository.ProcessDefinition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.configurationprocessor.json.JSONException;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.icode50.spring.entity.ProgressModel;
import com.icode50.spring.model.MyProcessDefinition;
import com.icode50.spring.model.param.ListParam;
import com.icode50.spring.model.result.Result;
import com.icode50.spring.model.result.ResultFactory;
import com.icode50.spring.service.serviceImpl.ProgressModelServiceImpl;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

/**
 * @author allenlin 
 * 流程引擎ProcessEngine
 * RepositoryService: 操作流程定义
 * RuntimeService: 操作流程实例
 * TaskService: 操作任务
 * IdentityService: 操作用户或组
 * HistoryService: 查询历史表数据
 * AuthorizationSercice: 授权相关服务
 * ManagementService: 执行cmd以及job相关服务 
 * FormService: 操作流程表单 
 * CaseService: CMMN相关操作
 * FilterService: 过滤相关服务
 * ExternalTaskService: 外部任务相关服务
 * DecisionService: DMMN相关操作
 */
@Api
@RestController
@RequestMapping("/api/camunda")
public class CamundaController {

	private final Logger LOGGER = LoggerFactory.getLogger(CamundaController.class);
    
	@Autowired
    private ProgressModelServiceImpl progressModelService;
    
	private final RepositoryService repositoryService;
	private final TaskService taskService;
	private final RuntimeService runtimeService;

	public CamundaController(RepositoryService repositoryService, TaskService taskService,
			RuntimeService runtimeService) {
		this.repositoryService = repositoryService;
		this.taskService = taskService;
		this.runtimeService = runtimeService;
	}

	/**
	 * 当前接口用于VueAdmin框架，传参为Json字符串
	 * 前端请求传Json对象则后端使用@RequestParam
	 * 前端请求传Json对象的字符串则后端使用@RequestBody
	 * @param data
	 * @return
	 * @throws JSONException
	 */
	@ApiOperation(value = "接口1:获取模型列表")
	@PostMapping(value = "/model-list")
	@ResponseBody
	public Result getModelerList(@RequestBody ListParam listParam) throws JSONException {
		Map<String, Object> paramMap = new HashMap<String, Object>();
		Integer page = listParam.getPage() != null ? listParam.getPage() : 1;
		Integer limit = listParam.getLimit() != null ? listParam.getLimit() : 20;
		String sort = listParam.getSort() != null ? listParam.getSort() : "";
		Integer startRow = (page - 1) * limit;
		Integer pageSize = limit;
		
		paramMap.put("startRow", startRow);
		paramMap.put("pageSize", pageSize);
		paramMap.put("sort", sort);
		
		List<ProgressModel> progressModelList = progressModelService.getProgressModelList(paramMap);

		if(progressModelList != null && progressModelList.size() > 0) {
			Map<String, Object> itemMap = new HashMap<String, Object>();
			itemMap.put("total", progressModelList.size());
			itemMap.put("items", progressModelList);
			return ResultFactory.bulidSuccessResult(itemMap);
		} else {
            String message = "数据获取失败！";
			return ResultFactory.bulidFailResult(message);
		}
	}
	
	/**
	 * @param data
	 * @return
	 * @throws JSONException
	 */
	@ApiOperation(value = "接口2: 创建模型")
	@PostMapping(value = "/create-model")
	@ResponseBody
	public Result createModel(@RequestBody ProgressModel progressModel) throws JSONException {
		progressModelService.addProgressModel(progressModel);
		Integer modelId = progressModel.getModelId();
		if(modelId != null && modelId > 0) {
			Map<String, Object> itemMap = new HashMap<String, Object>();
			itemMap.put("modelId", modelId);
			return ResultFactory.bulidSuccessResult(itemMap);
		} else {
            String message = "数据获取失败！";
			return ResultFactory.bulidFailResult(message);
		}
	}
	
	@ApiOperation(value = "接口3: 更新模型")
	@PostMapping(value = "/update-model")
	@ResponseBody
	public Result updateModel(@RequestBody ProgressModel progressModel) throws JSONException {
		Boolean isUpdate = progressModelService.updateProgressModel(progressModel);
		if(isUpdate != null && isUpdate == true) {
			Map<String, Object> itemMap = new HashMap<String, Object>();
			itemMap.put("progressModel", progressModel);
			return ResultFactory.bulidSuccessResult(itemMap);
		} else {
			String message = "数据获取失败！";
			return ResultFactory.bulidFailResult(message);
		}
	}
	
	@ApiOperation(value = "接口4: 根据ID获取模型")
	@PostMapping(value = "/get-model")
	@ResponseBody
	public Result getModel(@RequestBody ProgressModel paramModel) throws JSONException {
		ProgressModel progressModel = progressModelService.getProgressModelById(paramModel.getModelId());
		if(progressModel != null) {
			return ResultFactory.bulidSuccessResult(progressModel);
		} else {
			String message = "数据获取失败！";
			return ResultFactory.bulidFailResult(message);
		}
	}
	
	@ApiOperation(value = "接口5: 删除模型")
	@PostMapping(value = "/delete-model")
	@ResponseBody
	public Result deleteModel(@RequestBody ProgressModel progressModel) throws JSONException {
		progressModel.setStatus(4);
		Boolean isUpdate = progressModelService.updateProgressModel(progressModel);
		if(isUpdate != null && isUpdate == true) {
			Map<String, Object> itemMap = new HashMap<String, Object>();
			return ResultFactory.bulidSuccessResult(itemMap);
		} else {
			String message = "数据获取失败！";
			return ResultFactory.bulidFailResult(message);
		}
	}
	
	@ApiOperation(value = "接口5:获取流程列表")
	@PostMapping(value = "/progress-list")
	@ResponseBody
	public Result getProgressList(@RequestBody ListParam param) throws JSONException {
		Integer page = param.getPage() != null ? param.getPage() : 1;
		Integer limit = param.getLimit() != null ? param.getLimit() : 20;
		String sort = param.getSort() != null ? param.getSort() : "";
		LOGGER.info("获取流程列表, Page: " + page + ", Limit: " + limit + ", Sort: " + sort);
		LOGGER.info("获取流程列表, MinResult: " + ((page - 1) * limit) + ", MaxResult: " + (page * limit));
		List<ProcessDefinition> pdList = repositoryService.createProcessDefinitionQuery().orderByProcessDefinitionVersion().asc().listPage((page - 1) * limit, page * limit);
		List<MyProcessDefinition> pdeList = new ArrayList<MyProcessDefinition>();
		for (ProcessDefinition pd : pdList) {
			MyProcessDefinition pde = new MyProcessDefinition(pd.getId(), pd.getKey(), pd.getVersion(), pd.getCategory(),
					pd.getName(),pd.getDeploymentId(), pd.getResourceName(), pd.getHistoryTimeToLive(), 
					pd.getDiagramResourceName(), pd.getTenantId(), pd.getVersionTag(), pd.getHistoryTimeToLive());
			pdeList.add(pde);
		}
		if(pdeList != null && pdeList.size() > 0) {
			Map<String, Object> itemMap = new HashMap<String, Object>();
			itemMap.put("total", pdeList.size());
			itemMap.put("items", pdeList);
			return ResultFactory.bulidSuccessResult(itemMap);
		} else {
            String message = "数据获取失败！";
			return ResultFactory.bulidFailResult(message);
		}
	}
}
